#include <iostream>
#include <string>
#include <memory>

class Fruit
{
public:
    Fruit() {}
    virtual void show() = 0;
};

class Apple : public Fruit
{
public:
    Apple() {}
    virtual void show()
    {
        std::cout << "这是一个苹果" << std::endl;
    }
};

class Bannana : public Fruit
{
public:
    Bannana() {}
    virtual void show()
    {
        std::cout << "这是一个香蕉" << std::endl;
    }
};

class Animal
{
public:
    Animal() {}
    virtual void voice() = 0;
};

class Lamp : public Animal
{
public:
    virtual void voice()
    {
        std::cout << "山羊叫" << std::endl;
    }
};

class Dog : public Animal
{
public:
    virtual void voice()
    {
        std::cout << "狗叫" << std::endl;
    }
};

class Factory
{
public:
    virtual std::shared_ptr<Fruit> GetFruit(const std::string &name) = 0;
    virtual std::shared_ptr<Animal> GetAnimal(const std::string &name) = 0;
};

class FruitFactory : public Factory
{
    public:
    virtual std::shared_ptr<Fruit> GetFruit(const std::string& name)
    {
        if(name=="苹果")
        {
            return std::make_shared<Apple>();
        }
        else if(name=="香蕉")
        {
            return std::make_shared<Bannana>();
        }
        return std::shared_ptr<Fruit>();
    }

    virtual std::shared_ptr<Animal> GetAnimal(const std::string& name)
    {
        return std::shared_ptr<Animal>();
    }
};

class AnimalFactory:public Factory
{
    public:
    virtual std::shared_ptr<Fruit> GetFruit(const std::string& name)
    {
        return std::shared_ptr<Fruit>();
    }

    virtual std::shared_ptr<Animal> GetAnimal(const std::string& name)
    {
        if(name=="山羊")
        {
            return std::make_shared<Lamp>();
        }
        else if(name=="狗")
        {
            return std::make_shared<Dog>();
        }
        return std::shared_ptr<Animal>();
    }
};

class FactoryProducer
{
    public:
    static std::shared_ptr<Factory> GetFactory(const std::string& name)
    {
        if(name=="动物")
        {
            return std::make_shared<AnimalFactory>();
        }
        else
        {
            return std::make_shared<FruitFactory>();
        }
    }
};

int main()
{
    std::shared_ptr<Factory> fruitfactory=FactoryProducer::GetFactory("水果");
    std::shared_ptr<Fruit> fruit=fruitfactory->GetFruit("苹果");
    fruit->show();
    fruit=fruitfactory->GetFruit("香蕉");
    fruit->show();

    std::shared_ptr<Factory> animalfactory=FactoryProducer::GetFactory("动物");
    std::shared_ptr<Animal> animal=animalfactory->GetAnimal("山羊");
    animal->voice();
    animal=animalfactory->GetAnimal("狗");
    animal->voice();

    return 0;
}